package com.km.team.phsystem.web.controller;

import com.km.team.phsystem.beans.pojo.QueueInfo;
import com.km.team.phsystem.beans.pojo.SystemBusitype;
import com.km.team.phsystem.beans.pojo.TemporaryAppointment;
import com.km.team.phsystem.beans.vo.QueueInfoVo;
import com.km.team.phsystem.beans.vo.QueueListByBusinessIdListVo;
import com.km.team.phsystem.beans.vo.ResponseData;
import com.km.team.phsystem.common.constants.Constants;
import com.km.team.phsystem.common.enums.ReservationTypeEnum;
import com.km.team.phsystem.common.enums.ResultEnum;

import com.km.team.phsystem.common.utils.LocalDateUtil;
import com.km.team.phsystem.msg.service.ISmsService;
import com.km.team.phsystem.service.QueueNumberAssistService;
import com.km.team.phsystem.service.TemporaryAppointmentService;
import com.km.team.phsystem.service.TimeSlotPhConfigService;
import com.km.team.phsystem.web.controller.base.BaseController;
import com.km.team.phsystem.web.utils.ResponseDataUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Author: jiangjun、Riven
 * Date: 2018/10/15
 * Time: 下午4:48
 * Description:
 */
@RestController
@RequestMapping("/queue")
public class QueueController extends BaseController<QueueController> {

    private final ISmsService smsService;

    private final TimeSlotPhConfigService timeSlotPhConfigService;
    private final TemporaryAppointmentService temporaryAppointmentService;
    private final QueueNumberAssistService queueNumberAssistService;

    @Autowired
    public QueueController(ISmsService smsService,
                           TimeSlotPhConfigService timeSlotPhConfigService,
                           TemporaryAppointmentService temporaryAppointmentService,
                           QueueNumberAssistService queueNumberAssistService) {
        this.smsService = smsService;
        this.timeSlotPhConfigService = timeSlotPhConfigService;
        this.temporaryAppointmentService = temporaryAppointmentService;
        this.queueNumberAssistService = queueNumberAssistService;
    }

    @ApiOperation(value = "新用户加入排号队列", notes = "")
    @PostMapping("/add")
    public ResponseData add(@RequestBody @Valid QueueInfoVo vo,
                            BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            return ResponseDataUtil.buildError(ResultEnum.PARAM_ERROR);
        }
        String verifyResult = smsService.verifyIdentifyCode(vo.getMobile(), vo.getCheckCode());
        logger.info("排号短信验证结果：{}", verifyResult);
        if (StringUtils.isNotBlank(verifyResult) && !verifyResult.equals("success")) {
            return ResponseDataUtil.buildError(ResultEnum.VERIFY_CODE_ERROR);
        }

        if (ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT.getType().equals(vo.getReservationType())) {
            //临时业务，需要查看是否还有排号空间
            List<TemporaryAppointment> temporaryAppointments =
                this.temporaryAppointmentService.selectForBusinessId(Integer.valueOf(vo.getBusiType()));
            if (CollectionUtils.isEmpty(temporaryAppointments)) {
                return ResponseDataUtil.buildError(ResultEnum.PARAM_ERROR);
            }
            if (temporaryAppointments.get(0).getAcceptNo().equals(temporaryAppointments.get(0).getDoAcceptNo())) {
                return ResponseDataUtil.buildError(Constants.ERROR, "该时段业务受理数已用完，请重新选择其他时段！");
            }
        } else {
            //需要重新定义不能排号的情况
            //第一：该时段号以无受理数
            //第二：该用户已将在该业务类型下有排号
            //第三：该排号的时段小于开是受理钱一小时

            if (queueNumberAssistService.queueNumCheck(vo.getBusiType(), vo.getQueueDate(), vo.getQueueTimeSloeId())) {
                return ResponseDataUtil.buildError(Constants.ERROR, "该时段业务受理数已用完，请重新选择其他时段！");
            }
            List<QueueInfo> list = queueService.getQueueingByMobileAndBusiness(vo.getMobile(), vo.getBusiType());
            if (!CollectionUtils.isEmpty(list)) {
                return ResponseDataUtil.buildError(Constants.ERROR, "您还有排号未处理，不能再次排号！");
            }
            if (!isAftertartTime(vo.getQueueTimeSloeStart(), vo.getQueueDate())) {
                return ResponseDataUtil.buildError(Constants.ERROR, "您排号的时段已关闭，请重新选择时段！");
            }
        }
        vo.setMobile(vo.getMobile().replaceAll("\\s*", ""));
        String queueCode = queueService.add(vo);
        QueueInfo queueInfo = queueService.getDataByQueueCode(queueCode);
        SystemBusitype type = iSysBusiTypeService.getSystemBusiTypeByID(Integer.valueOf(queueInfo.getBusiType()));
        String date = LocalDateUtil.dateFormat(queueInfo.getDate(), "yyyy-MM-dd");
        if (ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType().equals(vo.getReservationType())) {
            date += " " + queueInfo.getTimeSlotStartStart();
            smsService.sendNoticeSms(queueInfo.getMobile(), date, queueInfo.getQueueCode(), type.getBusitype(),ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT);
        }else{
            smsService.sendNoticeSms(queueInfo.getMobile(), date, queueInfo.getQueueCode(), type.getBusitype(),ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT);
        }
        return ResponseDataUtil.buildSuccess(queueCode);
    }

    /**
     * 判断是当前排号时段是否合法
     *
     * @return
     */
    private boolean isAftertartTime(String startTime, String date) {
        Date date1 = LocalDateUtil.stampToDate(date);
        if (DateUtils.isSameDay(date1, new Date())) {
            LocalTime nowTime = LocalTime.now().withSecond(0).withNano(0);
            LocalTime start = LocalTime.parse(startTime).plusHours(1);
            if (nowTime.isAfter(start)) {
                return false;
            }
        }
        return true;

    }


    /**
     * 取消排号
     *
     * @param id
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "根据排号表ID，取消该条排号，如果是临时排号，维护临时排号表", notes = "")
    @GetMapping("/cancel/{id}")
    public ResponseData cancel(@PathVariable("id") Integer id) throws Exception {
        queueService.cancel(id);
        return ResponseDataUtil.buildSuccess();
    }


    /**
     * 我的预约排号
     *
     * @param mobile
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "根据电话号码查询自己的排号信息", notes = "")
    @GetMapping("/my/{mobile}/{checkCode}")
    public ResponseData my(@PathVariable("mobile") String mobile,
                           @PathVariable("checkCode") String checkCode) throws Exception {
        String verifyResult = smsService.verifyIdentifyCode(mobile, checkCode);
        logger.info("排号短信验证结果：{}", verifyResult);
        if (StringUtils.isNotBlank(verifyResult) && !verifyResult.equals("success")) {
            return ResponseDataUtil.buildError(ResultEnum.VERIFY_CODE_ERROR);
        }
        return ResponseDataUtil.buildSuccess(this.queueService.getDataForMobile(mobile));
    }


    /**
     * 办理下一个排号
     *
     * @param queueId
     * @param userId
     * @return
     * @throws Exception
     */
    @GetMapping("/next/{queueId}/{userId}")
    public ResponseData next(@PathVariable("queueId") Integer queueId,
                             @PathVariable("userId") Integer userId) throws Exception {
        queueService.dispatch(queueId, userId);
        return ResponseDataUtil.buildSuccess();
    }

    /**
     * 根据ID列表获取数据
     *
     * @param buinessIdList
     * @return
     */
    @ApiOperation(value = "根据业务ID列表和日期，获取格式化完成的排号数据列表", notes = "")
    @PostMapping("/time_slot/list")
    public ResponseData queueListByBusinessIdList(@RequestBody QueueListByBusinessIdListVo buinessIdList) throws Exception {
        return ResponseDataUtil.buildSuccess(queueService.queueListByBusinessIdList(buinessIdList.getBusinessIdList()
            , buinessIdList.getDate()));
    }

    /**
     * 根据ID列表获取临时排号数
     *
     * @param buinessIdList
     * @return
     */
    @ApiOperation(value = "根据业务ID列表，获取临时排号信息", notes = "")
    @PostMapping("/temporary")
    public ResponseData temporaryQueueListByBusinessIdList(@RequestBody QueueListByBusinessIdListVo buinessIdList) throws Exception {
        List<String> itemList = new ArrayList<>();
        buinessIdList.getBusinessIdList().forEach(item -> itemList.add(String.valueOf(item)));
        return ResponseDataUtil.buildSuccess(queueService.selectTemporaryQueue(itemList,
            buinessIdList.getDate()));
    }

    /**
     * 根据ID列表获取数据
     *
     * @param id
     * @return
     */
    @GetMapping("/info/{id}")
    @ApiOperation(value = "", notes = "")
    public ResponseData queueById(@PathVariable("id") Integer id) {
        return ResponseDataUtil.buildSuccess(queueService.selectQueueById(id));
    }

    /**
     * 绑定排号ID和窗口号，并修改状态
     *
     * @param id
     * @return
     */
    @GetMapping("/registration/{wind}/{id}")
    @ApiOperation(value = "关联窗口", notes = "")
    public ResponseData registrationWindAndQueueId(@PathVariable("wind") Integer wind, @PathVariable("id") Integer id) {
        queueService.registrationWindAndQueueId(wind, id);
        return ResponseDataUtil.buildSuccess();
    }

}
